#include "../include/timestamp.h"
#include <algorithm>



#if (defined(_MSC_VER))
#include <Windows.h>
#include <time.h>
static	x_int32	gettimeofday(struct timeval *tp, void *tzp)
{
	time_t clock;
	struct tm tm_now;
	SYSTEMTIME wtm;
	::GetLocalTime(&wtm);
	tm_now.tm_year    = wtm.wYear - 1900;
	tm_now.tm_mon     = wtm.wMonth - 1;
	tm_now.tm_mday    = wtm.wDay;
	tm_now.tm_hour    = wtm.wHour;
	tm_now.tm_min     = wtm.wMinute;
	tm_now.tm_sec     = wtm.wSecond;
	tm_now. tm_isdst  = -1;
	clock = mktime(&tm_now);
	tp->tv_sec = clock;
	tp->tv_usec = wtm.wMilliseconds * 1000;
	return (0);
}
#else
#include <sys/time.h>
#include    <stdio.h>
#endif // _MSVCR

namespace muradin{
namespace common
{
	timestamp::timestamp():millisecond_(0){}
	timestamp::timestamp(x_int64 millisecond):millisecond_(millisecond){}

#if (defined(_MSC_VER))
#pragma warning( push )
#pragma warning( disable : 4996 )
#endif // _MSVCR
	std::string		timestamp::to_string()const
	{
		char		time_str[64]={0};
		x_int64		seconds = (millisecond_ / milliseconds_one_second_);
		x_int64		millisecond=(millisecond_ % milliseconds_one_second_);

#if (defined(_MSC_VER))
		sprintf(time_str,"%I64d.%I64d",seconds,millisecond);
#else
		sprintf(time_str,"%lld%lld", seconds, millisecond);
#endif
		return time_str;
	}
	std::string		timestamp::to_formated_string()const
	{
		char	time_str[64]={0};
		time_t seconds = static_cast<time_t>(millisecond_ / milliseconds_one_second_);
		x_int32		millisecond=static_cast<x_int32>(millisecond_ % milliseconds_one_second_);
		struct tm* tm_time=NULL;

#if (defined(_MSC_VER))
		tm_time=::gmtime(&seconds);
#else
		struct tm tm_={0};
		tm_time = ::gmtime_r(&seconds,&tm_);
#endif
		if(tm_time){
			sprintf(time_str,"%04d-%02d-%02d %02d:%02d:%02d.%03d",
				tm_time->tm_year+1900,
				tm_time->tm_mon+1,
				tm_time->tm_mday,
				tm_time->tm_hour,
				tm_time->tm_min,
				tm_time->tm_sec,
				millisecond);
		}
		return time_str;
	}

#if (defined(_MSC_VER))
#pragma warning( pop )
#endif // _MSVCR

	x_int64			timestamp::millisecond()const
	{
		return millisecond_;
	}
	void			timestamp::swap(timestamp& tt)
	{
		std::swap (millisecond_,tt.millisecond_);
	}

	x_int32		timestamp::ms_of_second()
	{
		return milliseconds_one_second_;
	}

	timestamp		timestamp::now()
	{
		struct timeval now_time;
		gettimeofday(&now_time,NULL);
		x_int64 millisecond=now_time.tv_sec;
		millisecond = (millisecond * milliseconds_one_second_)
			+ (now_time.tv_usec / 1000);
		return timestamp(millisecond);
	}

};//namespace common
};//namespace muradin
